const localVideo = document.querySelector('video#localvideo');
const remoteVideo = document.querySelector('video#remotevideo');
const btnStart = document.querySelector('button#start');
const btnCall = document.querySelector('button#call');
const btnHangup = document.querySelector('button#hangup');

btnStart.onclick = start;
btnCall.onclick = call;
btnHangup.onclick = hangup;

const offer = document.querySelector('textarea#offer');
const answer = document.querySelector('textarea#answer');

function start(){
  if(
    !navigator.mediaDevices
    || !navigator.mediaDevices.getUserMedia
  ){
    console.error('the getUserMedia is not supported!');
    return;
  }else {
    const constrains = {
      video: true,
      audio: false
    };

    navigator.mediaDevices.getUserMedia(constrains)
      .then(getMediaStream)
      .catch(handleError)
  }
}

let localStream; // 后面会添加这个流

function getMediaStream(stream){
  localVideo.srcObject = stream;
  localStream = stream;

  btnStart.disabled = true;
  btnCall.disabled = false;
  btnHangup.disabled = true;
}

let pc1,
  pc2;

function call(){
  setTimeout(()=>{
    console.log('pc1.currentLocalDescription:',pc1.currentLocalDescription);
    console.log('pc1.currentLocalDescription:',JSON.stringify(pc1.currentLocalDescription));
  },2000)

  pc1 = new RTCPeerConnection({});
  console.log('pc1.iceGatheringState:',pc1.iceGatheringState);
  console.log('pc1.currentLocalDescription:',JSON.stringify(pc1.currentLocalDescription)); //搜索candidate, 你会发现此时一个也没有

  pc1.onicecandidate = (e/*RTCPeerConnectionIceEvent*/) => { //当pc1.setLocalDescription时 会触发底层的ice去搜集candidate 当每搜集到一个candidate后 会触发这里的回调
    //这里省略了信令传输
    console.log('pc1.iceGatheringState:',pc1.iceGatheringState);
    console.log('e.candidate:',e.candidate);
    console.log('pc1.currentLocalDescription:',JSON.stringify(pc1.currentLocalDescription)); //你会发现这里每on一个candidate, pc1的sdp中就会追加一个candidate
    pc2.addIceCandidate(e.candidate);
  };

  pc2 = new RTCPeerConnection({});
  pc2.onicecandidate = (e) => {
    //收到candidate后 会交给对方, 让对方插入到自己的candidate列表里去
    //这样后边就能够进行连通性检测
    //当检测完之后就可以传输数据了

    //这里省略了信令传输
    pc1.addIceCandidate(e.candidate);
  };

  //pc2是被调用者 当数据来了之后呢 它会触发ontrack这个事件
  pc2.ontrack = getRemoteStream

  // localStream.getTracks 获取所有的音视频轨
  console.log('localStream:',localStream);
  localStream.getTracks().forEach((track) => {
    console.log('localStream track:',track);
    pc1.addTrack(track, localStream); //表示把localStream这个流里的这个track通过pc1传输过去(包括localStream这个壳子)
    //这样在上面的pc2.ontrack 接受到的 e.streams 就会有这个 localStream 和这个 track
    //另外也可以不写第二个参数(localStream), 这样ontrack接受到的 e 的 streams里就没有流, 但此时我们可以通过e.track 拿到 track---> 参看 09.WebRTC端对端连接(p2p)/00.RTCPeerConnection/01.Stream(流)&Track(轨道)相关方法/00.addTrack和ontrack.md ---> Streamless tracks
    // 但此时要想这个track在video中被播放, 还是要在接受端接受到这个track后, 把它添加到一个 new MediaStream里, 再把这个new stream给到video才能播放
  });
  //↑ 这样就将本地采集的音视频流 添加到了 peerConnection

  //一定要先添加流↑ 再媒体协商↓
  const offerOptions = {
    offerToReceiveAudio: false,
    offerToReceiveVideo: true
  }
  pc1.createOffer(offerOptions)
    .then(getOffer)
    .catch(handleDescError)

  //其实放在这里不太妥当 应该是放在连接建立成功的时候 找一找对应的钩子 应该有
  btnCall.disabled = true;
  btnHangup.disabled = false;
}
function handleDescError(err){
  console.error('Failed to create offer:', err);
}


function getRemoteStream(e/*RTCTrackEvent*/){ //可能会有多个流, 在整个的WebRTC中呢, 每一路它是一路流, 在这个流里呢它包含了很多轨, 有音频轨、视频轨, 有多路音频轨、多路视频轨。
  console.log('ontrack e:',e);
  remoteVideo.srcObject = e.streams[0];
}

function getOffer(desc){
  pc1.setLocalDescription(desc); //此时会触发底层的ICE去搜集candidate ---> 然后搜集到后 会触发 pc1.onicecandidate回调
  offer.value = desc.sdp;

  //这里应该通过信令服务把sdp发送给对端, 我们这里省略了
  pc2.setRemoteDescription(desc);
  pc2.createAnswer()
    .then(getAnswer)
    .catch(handleAnswerError)
}
function handleAnswerError(err){
  console.error('Failed to create answer:', err);
}

function getAnswer(desc){
  pc2.setLocalDescription(desc);
  answer.value = desc.sdp;

  //同样的 这里省略了信令传输
  pc1.setRemoteDescription(desc);
}

//点hangup后第二个video就黑屏了(因为连接销毁了)
//但第一个还在（因为第一个我们是getUserMedia使用摄像头捕获的视频流赋给的video1, 是一直在的）
//当我们再点击start 它就又会创建peerconnection进行连接, 第二个video就又亮起来了
function hangup(){
  pc1.close();
  pc2.close();
  pc1 = null;
  pc2 = null;

  btnCall.disabled = false;
  btnHangup.disabled = true;
}

function handleError(err){
  console.error('Failed to get Media Stream!', err);
}


